#include <fhepython/PyFunc.h>
#include <fhepython/PyEnv.h>

namespace fhe
{
  using namespace core;
  namespace python
  {
    PyFunc::PyFunc( Node* node, boost::python::object func )
      : node_( node )
      , func_( func )
    {
    }
    
    std::string PyFunc::name() const
    {
      return boost::python::extract<std::string>( func_.attr( "__name__" ) );
    }
    
    Val PyFunc::call( const std::vector< Val >& args ) const
    {
      try
      {
        switch ( args.size() )
        {
          #define CALL_arg( z, n, unused ) PyEnv::instance().convertVal( args[n] )
        
          #define CALL_iter( z, n, unused ) \
            case n: \
              return PyEnv::instance().convertVal( func_( node_ BOOST_PP_COMMA_IF( n ) BOOST_PP_ENUM( n, CALL_arg, ~ ) ) ); \
              
          BOOST_PP_REPEAT( FHE_ARGS, CALL_iter, ~ )
          
          #undef CALL_iter
          #undef CALL_arg
        }
      }
      catch ( boost::python::error_already_set )
      {
        PyErr_Print();
        PyErr_Clear();
      }
    }
  }
}
